{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "5436020b",
   "metadata": {},
   "source": [
    "# How to create custom Tools\n",
    "\n",
    ":::info Prerequisites\n",
    "\n",
    "This guide assumes familiarity with the following concepts:\n",
    "\n",
    "- [LangChain tools](/docs/concepts#tools)\n",
    "- [Agents](/docs/concepts/#agents)\n",
    "\n",
    ":::\n",
    "\n",
    "When constructing your own agent, you will need to provide it with a list of Tools that it can use. While LangChain includes some prebuilt tools, it can often be more useful to use tools that use custom logic. This guide will walk you through how to use these `Dynamic` tools.\n",
    "\n",
    "In this guide, we will walk through how to do define a tool for two functions:\n",
    "\n",
    "1. A multiplier function that will multiply two numbers by each other\n",
    "2. A made up search function that always returns the string \"LangChain\"\n",
    "\n",
    "The biggest difference here is that the first function requires an object with multiple input fields, while the second one only accepts an object with a single field. Some older agents only work with functions that require single inputs, so it's important to understand the distinction."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "213ee344",
   "metadata": {},
   "source": [
    "## `DynamicStructuredTool`\n",
    "\n",
    "Newer and more advanced agents can handle more flexible tools that take multiple inputs. You can use the [`DynamicStructuredTool`](https://v02.api.js.langchain.com/classes/langchain_core_tools.DynamicStructuredTool.html) class to declare them. Here's an example - note that tools must always return strings!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "833dda4a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\u001b[32m\"72\"\u001b[39m"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import { DynamicStructuredTool } from \"@langchain/core/tools\";\n",
    "import { z } from \"zod\";\n",
    "\n",
    "const multiplyTool = new DynamicStructuredTool({\n",
    "  name: \"multiply\",\n",
    "  description: \"multiply two numbers together\",\n",
    "  schema: z.object({\n",
    "    a: z.number().describe(\"the first number to multiply\"),\n",
    "    b: z.number().describe(\"the second number to multiply\"),\n",
    "  }),\n",
    "  func: async ({ a, b }: { a: number; b: number; }) => {\n",
    "    return (a * b).toString();\n",
    "  },\n",
    "});\n",
    "\n",
    "await multiplyTool.invoke({ a: 8, b: 9, });"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c7326b23",
   "metadata": {},
   "source": [
    "## `DynamicTool`\n",
    "\n",
    "For older agents that require tools which accept only a single input, you can pass the relevant parameters to the [`DynamicTool`](https://v02.api.js.langchain.com/classes/langchain_core_tools.DynamicTool.html) class. This is useful when working with older agents that only support tools that accept a single input. In this case, no schema is required:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b0ce7de8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\u001b[32m\"LangChain\"\u001b[39m"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import { DynamicTool } from \"@langchain/core/tools\";\n",
    "\n",
    "const searchTool = new DynamicTool({\n",
    "  name: \"search\",\n",
    "  description: \"look things up online\",\n",
    "  func: async (_input: string) => {\n",
    "    return \"LangChain\";\n",
    "  },\n",
    "});\n",
    "\n",
    "await searchTool.invoke(\"foo\");"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Deno",
   "language": "typescript",
   "name": "deno"
  },
  "language_info": {
   "file_extension": ".ts",
   "mimetype": "text/x.typescript",
   "name": "typescript",
   "nb_converter": "script",
   "pygments_lexer": "typescript",
   "version": "5.3.3"
  },
  "vscode": {
   "interpreter": {
    "hash": "e90c8aa204a57276aa905271aff2d11799d0acb3547adabc5892e639a5e45e34"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
